<!--watch 监视-->
<template>

  <div>
    <p>姓名: {{ person.name }}</p>
    <p>年龄: {{ person.age }}</p>
    <p>座驾1: {{ person.car.first }}</p>
    <p>座驾2: {{ person.car.second }}</p>
    <button @click="changeName">修改姓名</button>
    <br>
    <button @click="changeAge">修改年龄</button>
    <br>
    <!-- <hr> 水平分割线 -->
    <button @click="changeFirstCar">修改第一台车</button>
    <button @click="changeSecondCar">修改第二台车</button>
    <button @click="changeFullCar">修改整台车</button>

    <h1 id="title">你好</h1>
    <button @click="getH1">获取h1标签</button>
  </div>
</template>

<style scoped>

</style>

<script setup lang="ts">
import {reactive, ref, toRef, watch} from "vue";
//
// // 情况三：监视【reactive】定义的【对象类型】数据
// let person = reactive({
//   name: '张三',
//   age: 18
// })
//
// function changeName() {
//   person.name += '~'
// }
//
// function changeAge() {
//   person.age += 1
// }
//
// function changePerson() {
//   Object.assign(person, {name: "lisi", age: 18})
// }
//
// // 监视 reactive 定义 对象类型 的数据，默认是开启深度监视的
// // 而且是不能改变的，即使我们通过 deep: false 去修改，也是无法关闭的
// watch(person, (newValue, oldValue) => {
//   // newValue 和 oldValue 类似于"指针"，都是指向监视对象的地址
//   // 如果监视对象的地址未发生变化，只是里面的值发生了变化，最终这两个值都是指向同一个对象
//   console.log(newValue, oldValue)
// })

let person = reactive({
  name: "张三",
  age: 18,
  car: {
    first: "奔驰",
    second: "宝马"
  }
})

function changeName() {
  person.name += '~'
}

function changeAge() {
  person.age += 1
}

function changeFirstCar() {
  person.car.first = '奥迪'
}

function changeSecondCar() {
  person.car.second = '雷克萨斯'
}

// 使用 reactive 定义的数据，不能使用直接使用 = 来重新赋值
// 但是其内部的对象属性并未使用 reactive 修饰，因此可以使用 = 来赋值
// 当然如果也使用 Object.assign 来赋值也正确
function changeFullCar() {
  // Object.assign(person.car, {first: "劳斯莱斯", second: "宾利"})
  person.car = {
    first: "劳斯莱斯",
    second: "宾利"
  }
}

// 监视对象内部的基本属性
// 这个基本属性类型不是ref定义的数据，因此无法监视
// 解决方法: 写一个函数，带有一个返回值
// 注意：这里不能使用 toRef 来转换
// watch(()=>person.name, (newValue, oldValue)=>{
//   console.log(newValue, oldValue)
// })

// 对象类型，可以直接写，也可以写函数
// 监视整体 -> 如果想要加上监视内部属性，可以开启深度监视
watch(() => person.car, (newValue, oldValue) => {
  console.log(newValue, oldValue)
}, {deep: true})

// 监视内部的属性
// watch(person.car, (newValue, oldValue)=>{
//   console.log(newValue, oldValue)
// })

// 总之一句话，直接使用函数来返回监视的值即可

// 如果想要监视多个属性的话，可以使用 数组[] 来包裹情况四

let title = ref()

function getH1() {
  console.log(title)
}
</script>
